package com.ec50n9.server.module.resource

import com.ec50n9.server.common.render
import com.ec50n9.server.module.common.CreateForm
import com.ec50n9.server.module.common.Render
import com.ec50n9.server.module.common.Rendered
import com.ec50n9.server.module.common.UpdateForm
import com.ec50n9.server.module.role.Role
import org.hibernate.annotations.GenericGenerator
import javax.persistence.*
import javax.validation.constraints.NotBlank

@Entity
class Resource(
    var name: String,
    @Column(unique = true)
    var code: String,
    var method: String,
    var uri: String,
    var status: Int = 1,

    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "resources")
    var roles: MutableSet<Role> = mutableSetOf(),

    @Id
    @GenericGenerator(name = "nanoid", strategy = "com.ec50n9.server.common.NanoIdGenerator")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "nanoid")
    var id: String? = null
) : Render<Resource>()

/**
 * 创建资源表单
 */
data class ResourceCreateForm(
    @field: NotBlank(message = "资源名称不能为空")
    var name: String? = null,

    @field: NotBlank(message = "资源代码不能为空")
    var code: String? = null,

    @field: NotBlank(message = "请求方法不能为空")
    var method: String? = null,

    @field: NotBlank(message = "请求uri不能为空")
    var uri: String? = null,

    var status: Int? = 1
) : CreateForm<Resource> {
    override fun renderTo(): Resource {
        val resource = Resource("", "", "", "")
        render(resource)
        return resource
    }
}

/**
 * 更新资源表单
 */
data class ResourceUpdateForm(
    var name: String? = null,
    var code: String? = null,
    var method: String? = null,
    var uri: String? = null,
    var status: Int? = null
) : UpdateForm<Resource> {
    override fun renderTo(target: Resource) {
        render(target, true)
    }
}

/**
 * 查询渲染
 */
data class ResourceQueryRendered(
    var name: String? = null,
    var code: String? = null,
    var method: String? = null,
    var uri: String? = null,
    var status: Int? = null
) : Rendered<Resource> {
    override fun renderFrom(from: Resource) {
        from.render(this)
    }
}